package projectUtils;

import java.util.ArrayList;
import java.util.List;

public class ProjectionRunLength {

	private byte[][] data;
	
	public ProjectionRunLength(byte[][] data)
	{
		this.data = data;
	}
	
	public List<Integer> GetRunLengthXProjection(int tolerance)
	{
		List<Integer> returnValue = new ArrayList<Integer>(data.length);
		for (int i = 0; i < data.length; i++)
		{
			int longestRun = 0;
			int currentRun = 0;
			int toleranceCounter = 0;
			for (int j = 0; j < data[i].length; j++)
			{
				if (ByteUtil.ByteToInt(data[i][j]) < 255)
				{
					currentRun ++;
					toleranceCounter = 0;
				}
				else
				{
					if (currentRun > 0)
					{
						toleranceCounter++;
						if (toleranceCounter > tolerance)
						{
							if (currentRun > longestRun)
								longestRun = currentRun;
							currentRun = 0;
							tolerance = 0;
						}
					}
				}
			}
			if (currentRun > longestRun)
				longestRun = currentRun;
			returnValue.add(longestRun);
		}
		return returnValue;
	}
	
	public void GetRunLengthXProjectionIndices(int tolerance, int xIndex, int[] indices)
	{
		int longestRun = 0;
		int currentRun = 0;
		int toleranceCounter = 0;
		int beginIndex = 0;
		int endIndex = data[xIndex].length - 1;
		int bestBeginIndex = 0;
		int bestEndIndex = endIndex;
		for (int j = 0; j < data[xIndex].length; j++)
		{
			if (ByteUtil.ByteToInt(data[xIndex][j]) < 255)
			{
				if (currentRun == 0)
					beginIndex = j;
				endIndex = j;
				currentRun ++;
				toleranceCounter = 0;
			}
			else
			{
				if (currentRun > 0)
				{
					toleranceCounter++;
					if (toleranceCounter > tolerance)
					{
						if (currentRun > longestRun)
						{
							longestRun = currentRun;
							bestBeginIndex = beginIndex;
							bestEndIndex = endIndex;
						}
						currentRun = 0;
						tolerance = 0;
					}
				}
			}
		}
		if (currentRun > longestRun)
		{
			longestRun = currentRun;
			bestBeginIndex = beginIndex;
			bestEndIndex = endIndex;
		}
		indices[0] = bestBeginIndex;
		indices[1] = bestEndIndex;
	}
	
	public List<Integer> GetHorizontalBlackRLE()
	{
		List<Integer> rle = new ArrayList<Integer>();
		for (int i = 0; i < data[0].length; i++)
			rle.add(0);

		int curMatched;
		for (int i = 0; i < data[0].length; i++)
		{
			curMatched = 0;
			for (int j = 0; j < data.length; j++)
			{
				int rgb = ByteUtil.ByteToInt(data[i][j]);
				if (ColorUtil.RGBToGreyScale(rgb) < 255)
				{
					curMatched++;
				}
				else
				{
					if (curMatched > 0)
					{
						rle.set(curMatched, rle.get(curMatched) + 1);
						curMatched = 0;
					}
				}
			}
		}
		return rle;
	}
}
